package com.weyoung.app.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weyoung.app.dto.req.ModFamTraDTO;
import com.weyoung.app.mapper.FamilyMapper;
import com.weyoung.app.mapper.UserMapper;
import com.weyoung.app.service.FamilyService;
import com.weyoung.app.service.UserService;
import com.weyoung.common.consatant.exception.AbstractException;
import com.weyoung.common.consatant.exception.ClientException;
import com.weyoung.common.consatant.result.Result;
import com.weyoung.common.model.dto.app.CreateFamilyDTO;
import com.weyoung.common.model.entity.Family;
import com.weyoung.common.model.entity.UserDO;
import com.weyoung.common.model.entity.UserDetailDO;
import com.weyoung.common.model.vo.app.FamilyVO;
import com.weyoung.common.model.vo.app.UserDetailVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.weyoung.common.consatant.errorcode.BaseErrorCode.SERVICE_ERROR;
import static com.weyoung.common.utils.RedisConstants.*;


/**
* @author 27675
* @description 针对表【family(家族信息表)】的数据库操作Service实现
* @createDate 2025-04-14 12:04:21
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class FamilyServiceImpl extends ServiceImpl<FamilyMapper, Family> implements FamilyService {

    private final FamilyMapper familyMapper;

    private final StringRedisTemplate stringRedisTemplate;

    private final UserService userService;

    private final UserMapper userMapper;

    /**
     * 修改家风
     * @param modFamTraDTO
     * @return
     */
    @Override
    public Result modifyFamilyMotto(ModFamTraDTO modFamTraDTO) {
        UserDO currentUser = getCurrentUser();
        // 1. 参数校验
        if (modFamTraDTO == null) {
            log.error("修改家族家风失败: 参数不能为空");
            return Result.failure("1", "参数不能为空");
        }

        if (StringUtils.isBlank(modFamTraDTO.getFamilyMotto())) {
            log.error("修改家族家风失败: familyMotto不能为空");
            return Result.failure("1","家族箴言不能为空");
        }

        try {
            // 2. 业务逻辑处理
            // 添加用户所属家族id
            if (currentUser.getFamilyId() == null){
                throw new ClientException("用户未关联家族");
            }
            modFamTraDTO.setFamilyId(currentUser.getFamilyId());
            int affectedRows = familyMapper.updateFamTraById(modFamTraDTO);
            // 3. 结果处理
            if (affectedRows <= 0) {
                log.warn("修改家族家风失败: 未找到对应记录, familyId={}", modFamTraDTO.getFamilyId());
                return Result.failure("1","修改失败，未找到对应家族记录");
            }
            log.info("成功修改家族家风, familyId={}", modFamTraDTO.getFamilyId());
            // 删除缓存
            stringRedisTemplate.delete(FAMILY_MOTTO_KEY + modFamTraDTO.getFamilyId());
            return Result.success(affectedRows);
        } catch (Exception e) {
            log.error("修改家族家风异常, familyId={}", modFamTraDTO.getFamilyId(), e);
            return Result.failure((AbstractException) e);
        }
    }

    /**
     * 查看家族家风
     * @return
     */
    @Override
    public Result getFamilyMotto() {
        UserDO currentUser = getCurrentUser();
        String familyId = currentUser.getFamilyId();
        if (familyId == null){
            throw new ClientException("用户未关联家族");
        }
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(FAMILY_MOTTO_KEY + familyId))){
            // 如果存在，直接返回缓存数据
            // 判断缓存数据是否为空
            String familyMotto = stringRedisTemplate.opsForValue().get(FAMILY_MOTTO_KEY + familyId);
            if (StrUtil.isBlank(familyMotto)){
                // 如果为空，返回失败
                return Result.failure("1","未找到对应家族记录");
            }
            // 如果不为空，返回成功
            return Result.success(familyMotto);
        }
        // 缓存中没有，则查找数据库
        String familyMotto = familyMapper.getFamilyTradition(familyId);
        if (StrUtil.isBlank(familyMotto)){
            // 如果数据库中没有，返回失败
            // 存入空数据入缓存
            stringRedisTemplate.opsForValue().set(FAMILY_MOTTO_KEY + familyId, "");
            stringRedisTemplate.expire(FAMILY_MOTTO_KEY + familyId, NULL_EXPIRE_TIME, TimeUnit.SECONDS);
            return Result.failure("1","未找到对应家族记录");
        }
        // 如果数据存在，存入缓存，设置过期时间
        stringRedisTemplate.opsForValue().set(FAMILY_MOTTO_KEY + familyId, familyMotto);
        // 设置缓存过期时间 + 随机时间
        stringRedisTemplate.expire(FAMILY_MOTTO_KEY + familyId, FAMILY_MOTTO_EXPIRE_TIME + RandomUtil.randomLong(20), TimeUnit.SECONDS);
        return Result.success(familyMotto);
    }

    /**
     * 获取当前登录用户信息
     * @return 用户实体
     * @throws ClientException 获取用户失败时抛出
     */
    private UserDO getCurrentUser() {
        try {
            if (!StpUtil.isLogin()) {
                throw new ClientException("用户未登录");
            }

            Integer userId = Integer.parseInt(StpUtil.getLoginId().toString());
            UserDO user = userService.getById(userId);

            if (user == null) {
                throw new ClientException("用户不存在");
            }

            if (user.getFamilyId() == null) {
                throw new ClientException("用户未关联家族");
            }

            return user;
        } catch (Exception e) {
            log.error("获取当前用户信息失败，异常信息: {}", e.getMessage(), e);
            throw new ClientException("获取用户信息失败", e,SERVICE_ERROR);
        }
    }

    @Override
    @Transactional
    public void createFamily(CreateFamilyDTO dto) {
        // 获取当前用户ID
        Integer currentUserId = StpUtil.getLoginIdAsInt();

        // 检查用户是否已经有家族
        UserDO user = userMapper.selectById(currentUserId);
        if (user.getFamilyId() != null) {
            throw new ClientException("您已经加入了家族，不能创建新的家族");
        }

        // 创建家族记录
        Family family = new Family();
        BeanUtil.copyProperties(dto, family);
        
        // 设置家族ID和创建者ID
        family.setFamilyId(UUID.randomUUID().toString());
        family.setCreatorId(currentUserId);
        family.setCreateDate(new Date());
        family.setUpdateDate(new Date());

        // 保存家族信息
        save(family);

        // 更新用户的家族ID
        user.setFamilyId(family.getFamilyId());
        userMapper.updateById(user);

    }

    @Override
    public FamilyVO getFamily() {

        FamilyVO familyVO = new FamilyVO();

        // 获取当前用户ID
        Integer currentUserId = StpUtil.getLoginIdAsInt();
//        Integer currentUserId = 1003;
        
        // 获取用户所属家族ID
        UserDO user = userMapper.selectById(currentUserId);
        if (user == null || StringUtils.isEmpty(user.getFamilyId())) {
            // 用户未关联家族，返回空对象
            return familyVO;
        }
        
        // 获取家族信息
        Family family = this.getById(user.getFamilyId());
        if (family == null) {
            throw new ClientException("家族不存在");
        }

        BeanUtil.copyProperties(family, familyVO);
        
        return familyVO;
    }
}




